<template>
   <!-- 三级列表 -->
   <Category :disabled="isShowList"/>

   <el-card shadow="always" :body-style="{ padding: '20px' }" :style="{marginTop: '40px'}">
    <!-- 商品属性表格 -->
    <template #header v-if="!isShowList">
        <el-button :disabled="!category3Id" type="primary" size="default" :icon="CirclePlusFilled" @click="addAttr">添加</el-button>
    </template>
    <el-table :data="tableData" border stripe :style="{marginTop: '40px'}" v-if="!isShowList">
        <el-table-column type="index" width="120" label="序号" align="center"/>
        <el-table-column label="属性名称" width="180px" prop="attrName"/>
        <el-table-column label="属性值名称列表">
            <template #="{row}">
                <el-tag 
                    :style="{marginRight: '20px'}"
                    type="success" 
                    size="default" 
                    v-for="item in row.attrValueList"
                    :key="item.id"
                    :closable="row.isDelete"
                >{{item.valueName}}</el-tag>
            </template>
        </el-table-column>
        <el-table-column label="操作" width="180px" align="center">
            <template v-slot="{row}">
                <el-button type="warning" size="default" :icon="Edit" @click="updateAttr(row)"></el-button>
                <!-- 气泡确认框 -->
                <el-popconfirm title="确定要删除吗?" @confirm="deleteAttr(row.id)">
                        <template #reference>
                            <el-button type="danger"  :icon="Delete"></el-button>
                        </template>
                </el-popconfirm>
            </template>
        </el-table-column>
    </el-table>

    <!-- 添加或者修改商品属性 -->
    <div v-else>
        <!-- 输入属性名表单 -->
        <el-form :inline="true">
            <el-form-item label="属性名">
                <el-input placeholder="输入属性名" v-model="newAttr.attrName"></el-input>
            </el-form-item>
        </el-form>
        <!-- 添加属性名和取消按钮 -->
        <div>
            <el-button :disabled="!newAttr.attrName" type="primary" @click="addAttrValue" >添加属性值</el-button>
            <el-button  @click="isShowList = false" >取消</el-button>
        </div>
        <!-- 属性值表格 -->
        <el-table :data="newAttr.attrValueList" border stripe :style="{marginTop: '30px' , marginBottom: '30px'}">
            <el-table-column type="index" width="100" align="center" label="序号"/>
            <el-table-column label="属性值名称">
                <template v-slot="{row , $index}">
                    <span 
                        v-if="!row.isEdit"
                        :style="{display: 'inline-block' , width: '80%'}"
                        @click="toEdit(row)"
                    >
                        {{row.valueName}}
                    </span>
                    <el-input
                        v-else 
                        v-model="row.valueName" 
                        ref="inputEle"
                        @focus="getOldAttrValueName(row)"
                        @blur="toLook(row , $index)"
                    ></el-input>
                </template>
            </el-table-column>
            <el-table-column label="操作">
                <template #="{$index}">
                    <!-- 气泡确认框 -->
                    <el-popconfirm title="确定要删除吗?" @confirm="deleteAttrValue($index)">
                        <template #reference>
                            <el-button type="danger"  icon="ele-Delete"></el-button>
                        </template>
                    </el-popconfirm>
                </template>
            </el-table-column>
        </el-table>
        <!-- 保存和取消按钮 -->
        <div>
            <el-button :disabled="newAttr.attrValueList.length<=0 || !newAttr.attrName" type="primary" @click="addOrUpdateAttr" >保存</el-button>
            <el-button  @click="isShowList = false" >取消</el-button>
        </div>
    </div>

   </el-card>


</template>

<script lang="ts">
import { defineComponent } from "vue";
import { storeToRefs } from "pinia";
import { ElMessage } from "element-plus";
import {Delete , Edit} from "@element-plus/icons-vue"

export default defineComponent({
    name: "Attr",
});
</script>

<script setup lang="ts">
import { CirclePlusFilled } from "@element-plus/icons-vue"; 
import useAttrStore from "@/stores/category";
import {watch , ref, nextTick} from "vue"
import type {reqAttrListType , reqAttrItmType , reqAttrValueItmeType} from "@/api/attr"
import  {requestAttrList  , requestUpdateOrAddAttr , requestDeleteAttr} from "@/api/attr"
import {ElMessageBox} from 'element-plus'
import  cloneDeep  from "lodash/cloneDeep";

const attrStore = useAttrStore()
const {category1Id ,category2Id , category3Id}  = storeToRefs(attrStore)


//定义表格数据
const tableData = ref<reqAttrListType>([])
//封装请求商品属性列表的函数
const getAttrList = async () => {
    try {
        //请求商品属性列表
        const result = await requestAttrList(
        category1Id.value as number,
        category2Id.value as number,
        category3Id.value as number,
        )
        //把请求回来的数据给表格数据
        tableData.value = result
    } catch (error) {
        //请求失败提示
        ElMessage.error("请求商品属性列表失败")
    }  
}
//1.监听category3Id的改变请求商品属性列表
watch(category3Id , async(newValue) => {
    //再次点击一级二级列表会把category3Id清空,不用请求商品属性列表,把列表清空
    if(newValue === null){
        tableData.value = []
        return
    }
    //请求商品属性列表
    getAttrList()
} , {immediate: true})


//2.添加或修改逻辑
//定义数据控制显示异常添加修改页面
const isShowList = ref(false)
//定义要添加或者修改的数据
const newAttr = ref<reqAttrItmType>({
    attrName: "",  
    categoryId: category3Id.value as number, 
    categoryLevel: 3, 
    attrValueList: []
})

//2.1点击添加的逻辑
const addAttr = () => {
    //展示添加或修改页
    isShowList.value = true
    //清空之前的数据
    newAttr.value = {
        attrName: "",  
        categoryId: category3Id.value as number, 
        categoryLevel: 3, 
        attrValueList: []
    }
}

//2.2点击修改的回调
const updateAttr = (row: reqAttrItmType) => {
    //展示添加或修改页
    isShowList.value = true
    //拷贝要修改的数据
    const newRow = cloneDeep(row)
    //给属性值数组的每一项添加一个值，为了控制是编辑模式还是查看模式
    newRow.attrValueList.forEach((item) => {
        item.isEdit = false
    })
    //回填数据
    newAttr.value = newRow
}


//获取input
const inputEle = ref()
//定义旧值
let oldAttrValueName = ""
//input获取焦点的回调
const getOldAttrValueName = (row: reqAttrValueItmeType) => {
    oldAttrValueName = row.valueName
}


//2.3点击添加属性值的回调 --创建数据插入，并获取焦点
const addAttrValue = () => {
    //创建一个要添加的属性值数据
    const newAttrValue = ref<reqAttrValueItmeType>({
        valueName: "",    //属性值名称
        attrId: 0,        //属性id
        isEdit: true      //新添加的是编辑状态
    })
    //把新数据插入到newAttr
    newAttr.value.attrValueList.push(newAttrValue.value)
    //添加后获取焦点 为了获取旧值
    nextTick(() => {
        inputEle.value.focus()
    })
}


//2.4点击span切换为编辑模式并获取焦点
const toEdit = (row: reqAttrValueItmeType) => {
    //切换到input编辑模式
    row.isEdit = true
    //获取焦点
    nextTick(() => {
        inputEle.value.focus()
    })
}

//2.6失去焦点切换为查看模式
const toLook = (row: reqAttrValueItmeType , $index: number) => {
    //切换到ispan查看状态
    row.isEdit = false

    //判断输入为空
    if(!row.valueName){
            //旧值为空，说明用户添加了一个空值，我们把它删除
        if(!oldAttrValueName){
            newAttr.value.attrValueList.splice($index , 1)
        }else{
            //有旧值，说明用户把一个数据改为空，我们恢复他
            row.valueName = oldAttrValueName
        }
    }

    //判断重复，不和修改后的自己比较
    const isRepect = newAttr.value.attrValueList.some((item) => {
        if(item === row) return
        return item.valueName === row.valueName
    })
    //重复有两种情况
    if(isRepect){
            //有旧值，说明用户修改后的值重复了，我们恢复
        if(oldAttrValueName){
            row.valueName = oldAttrValueName
        }else{
            //没有旧值，说明用户添加了一个重复的值，我们删除它
            newAttr.value.attrValueList.splice($index , 1)
        }
    }

    //失去焦点后清空旧值，为了下次获取焦点逻辑
    oldAttrValueName = ""
}

//2.7点击删除属性值的回调
const deleteAttrValue = (index: number) => {
    newAttr.value.attrValueList.splice(index  , 1)
}

//2.8点击保存的回调
const addOrUpdateAttr = async () => {
    try {
        //发送请求
        await requestUpdateOrAddAttr(newAttr.value)
        //成功提示
        ElMessage.success(newAttr.value.id? '修改成功!' : '添加成功!')
        //回到商品属性列表
        isShowList.value = false
        //重新请求商品列表
        getAttrList()
    } catch (error) {
        //失败提示
        ElMessage.error(newAttr.value.id? '修改失败!' : '添加失败!')
    }
}

//2.9点击删除商品属性的回调
const deleteAttr = async (id: number) => {
    try {
        //发送删除请求
        await requestDeleteAttr(id)
        //成功提示
        ElMessage.success("删除成功!")
        //重新请求商品属性列表
        getAttrList()
    } catch (error) {
        //失败提示
        ElMessage.error("删除失败！")
    }
}




</script>